home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / e / amigae30a_fr.lha / AmigaE30f / Sources / Pd / ARexxPort.e < prev    next >
Encoding:
Text File  |  1994-12-02  |  9.6 KB  |  367 lines

  1. /* FOLD info
  2.         ~~~~ */
  3.  
  4. /* ARexxPort.e 1.0 - par Leon Woestenberg (leon@stack.urc.tue.nl) */
  5. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  6. /*
  7.  
  8.    Je présente ici quelques fonctions de base pour rendre vos
  9.    programmes E capable de communiquer avec d'autres programmes
  10.    multitaches via AREXX. Avec ces fonctions vos programmes
  11.    pourront:
  12.  
  13.    · Recevoir et réagir aux commandes ARexx qui ont été envoyé.
  14.    · Appeler Rexx Master pour lancer des commandes que votre programme
  15.      ne comprend pas. Ce peut être des script AREXX (dans REXX:) aussi.
  16.    · Envoyer des commandes AREXX à d'autres programmes ou à Rxx Master.
  17.  
  18.    Ce source est du domaine public alors utilisez le :)
  19.  
  20.    Le source est abondamment commeté et s'explqie quasiment par lui-même.
  21.    La chse la plus dur est : Quand un message AREXX arrivant contient
  22.    une commande qui n'est pas supporté par votre programme, ce message
  23.    n'est pas renvoyé DE SUITE. D'abord, un nouveau message est créé et
  24.    envoyé à Rexx Master. On peut enlever  le premier message de la mémoire
  25.    (en utilisant le pointeur). De cette façon, les scripts AREXX peuvent
  26.    être utilisé avec des commandes AREXX. Notez que l'extension par défaut
  27.    de ces scripts peut être adapté à votre programme dans la procédure
  28.    sendRexxMsg.
  29.  
  30.    ARexx ajoute une grande possibilité à votre Amiga multitache, comme
  31.    des taches qui interagissent en temps réel entre eux, comme ça il peuvent
  32.    utiliser les caractèristique des autres. Pensez au possibilité offerte à
  33.    vos programmes étendus avec une interface ARexx.
  34.  
  35.    Si vous avez des questions, suggestions, ou report d'erreurs, joignez moi
  36.    via Internet. Les questions/discussions générale sur ce source sont
  37.    aussi les bienvenues sur l'Amiga E mailing list.
  38.  
  39.                               Leon Woestenberg (leon@stack.urc.tue.nl)
  40.  
  41. */
  42. /* FEND */
  43. /* FOLD "modules" */
  44.  
  45. MODULE 'exec/ports','exec/nodes'
  46. MODULE 'rexxsyslib','rexx/rexxio','rexx/rxslib','rexx/errors','rexx/storage'
  47. MODULE 'dos/dos'
  48.  
  49. /* FEND */
  50. /* FOLD "definitions" */
  51.  
  52. DEF hostport=NIL:PTR TO mp
  53. DEF runflag=TRUE
  54. DEF unconfirmed=0
  55.  
  56. /* FEND */
  57.  
  58. /* FOLD "main" */
  59. PROC main() HANDLE
  60.  
  61.   /* open rexx library */
  62.   IF (rexxsysbase:=OpenLibrary('rexxsyslib.library',0))
  63.  
  64.     /* créé un port hôte pour arexx */
  65.     IF (hostport:=createPort('HoteExemple',0))
  66.  
  67.     /* exemples de votre proramme envoyant des cxommandes arexx à d'autres
  68.        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  69.  
  70.     /*
  71.  
  72.     /* Dit à GoldED de déplacer le curseur d'une ligne vers le haut */
  73.     sendRexxMsg('GOLDED.1','UP',NIL,0)
  74.  
  75.     /* dit au shell d'éxécuter la commande list */
  76.     sendRexxMsg('REXX','"ADDRESS COMMAND list"',NIL,0)
  77.  
  78.     /* lance un script depuis REXX: (mettez l'extension par défaut dans sendRexxMsg) */
  79.     sendRexxMsg('REXX','scriptname',NIL,0)
  80.  
  81.     /* envoie une commande 'QUIT' à nous même :o) */
  82.     sendRexxMsg('HoteExemple','QUIT',NIL,0)
  83.  
  84.     */
  85.  
  86.     /* informe l'utilisateur que ça marche */
  87.     WriteF('Attend des évènements. Envoyez moi une commande arexx QUIT en tapant:\nrx "ADDRESS \aHoteExemple\a; QUIT" depuis un shell. Ou pressez CTRL-C pour m\aarrêter.\n')
  88.  
  89.     /* attend */
  90.     wait()
  91.  
  92.     deletePort(hostport)
  93.     ELSE
  94.       WriteF('Désolé bonhomme, je crois que je tourne déja une fois.\n')
  95.     ENDIF
  96.     CloseLibrary(rexxsysbase)
  97.   ELSE
  98.     WriteF('Ne peut pas ouvrir la rexxsyslib.library. J\aen ai vraiment besoin!\n')
  99.   ENDIF
  100. EXCEPT
  101.   WriteF('Quleque chose comme \d n'a pas marché, tu vois?\n')
  102.   deletePort(hostport)
  103.   hostport:=NIL
  104.   IF rexxsysbase
  105.     CloseLibrary(rexxsysbase)
  106.     rexxsysbase:=NIL
  107.   ENDIF
  108. ENDPROC
  109. /* FEND */
  110. /* FOLD "wait" */
  111. PROC wait()
  112.  
  113.   DEF signalmask=0
  114.   DEF hostmask=0
  115.  
  116.   /* masque signal pour notre port hôte */
  117.   hostmask:=Shl(1,hostport.sigbit)
  118.  
  119.   /* continue à tourner ou messages non confirmés? */
  120.   WHILE runflag OR unconfirmed
  121.  
  122.     /* attend les signaux d'évènements */
  123.     signalmask:=Wait(hostmask OR SIGBREAKF_CTRL_C)
  124.  
  125.     /* et gère les évènements qui arrive */
  126.     IF signalmask AND hostmask THEN handleRexxMsg()
  127.     IF signalmask AND SIGBREAKF_CTRL_C THEN runflag:=FALSE
  128.  
  129.   ENDWHILE
  130. ENDPROC
  131. /* FEND */
  132.  
  133. /* FOLD "handleRexxMsg" */
  134. PROC handleRexxMsg()
  135.  
  136.   /* pointeur sur le message à gérer */
  137.   DEF rexxmsg:PTR TO rexxmsg
  138.   /* pointeur sur messagenode */
  139.   DEF msgnode:PTR TO mn
  140.   /* pointeur sur la liste de noeuds du message */
  141.   DEF listnode:PTR TO ln
  142.  
  143.   /* liste de 16 pointers sur les chaines de commande */
  144.   DEF rexxargs:PTR TO LONG
  145.  
  146.   /* pointe sur le premier caractère de la commande */
  147.   DEF command:PTR TO CHAR
  148.  
  149.   /* (un autre) message à la queue? */
  150.   WHILE rexxmsg:=GetMsg(hostport)
  151.  
  152.     /* met le pointeur sur messagenode */
  153.     msgnode:=rexxmsg.mn
  154.  
  155.     /* met le pointeur sur la liste de noeuds */
  156.     listnode:=msgnode.ln
  157.  
  158.     /* met le pointeur sur les commands */
  159.     rexxargs:=rexxmsg.args
  160.  
  161.     /* réponse de confirmation d'un message envoyé par nous? */
  162.     IF listnode.type=NT_REPLYMSG
  163.  
  164.       /* original message pointer present? */
  165.       IF rexxargs[15]
  166.         /* répond au message original */
  167.         ReplyMsg(rexxargs[15])
  168.       ENDIF
  169.  
  170.       /* efface ce message de confirmation */
  171.       DeleteArgstring(rexxargs[0])
  172.       DeleteRexxMsg(rexxmsg)
  173.  
  174.       /* diminue le compteur non-confirmé */
  175.       DEC unconfirmed
  176.  
  177.     /* un tout nouveau message */
  178.     ELSE
  179.  
  180.       /* pointe sur la commande après avoir sautés les espaces etc. */
  181.       command:=TrimStr(rexxargs[0])
  182.       WriteF('We received an ARexx command: \s\n',command)
  183.  
  184.       /* initialise les codes sortants */
  185.       rexxmsg.result1:=0
  186.       rexxmsg.result2:=NIL
  187.  
  188.       /* exemple de gestion d'une commande que quequ'un nous a envoyé
  189.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  190.  
  191.       /* command known? */
  192.       IF StrCmp('QUIT',command,ALL)
  193.         WriteF('So let\as quit here.\n')
  194.         runflag:=FALSE
  195.         ReplyMsg(rexxmsg)
  196.  
  197.       /* commande inconnue */
  198.       ELSE
  199.         WriteF('Hmmm. Commance inconnue. On l'envoie à Rexx Master...\n')
  200.  
  201.         /* on fait suivre cette commande à rexx master (peut-être c'est un script?) */
  202.         /* le message original n'est pas répondu pour le moment */
  203.         /* tant qu'on n'a pas eu confirmation de rexx master. */
  204.         /* Pour cela, on garde ce message dans un pointeur de message rexxargs[15] */
  205.         /* in rexxargs[15] de la commande envoyée à Rexx Master */
  206.  
  207.         /* message ne peut pas être envoyé à rexx? */
  208.         IF sendRexxMsg('REXX',rexxargs[0],rexxmsg,0)=NIL
  209.  
  210.           /* met le code de retour : erreur fatale */
  211.           xReplyRexxCmd(rexxmsg,RC_FATAL,NIL)
  212.  
  213.           /* répond au message */
  214.           ReplyMsg(rexxmsg)
  215.  
  216.         ENDIF
  217.       ENDIF
  218.     ENDIF
  219.   ENDWHILE
  220. ENDPROC
  221. /* FEND */
  222. /* FOLD "sendRexxMsg(hostname,command,unknownmsg,flags)" */
  223. PROC sendRexxMsg(hostname,command,unknownmsg,flags)
  224.  
  225.   DEF arexxport=NIL:PTR TO mp
  226.   DEF rexxmsg=NIL:PTR TO rexxmsg
  227.   DEF rexxargs:PTR TO LONG
  228.   DEF listnode=NIL:PTR TO ln
  229.   DEF temp=NIL
  230.  
  231.   /* retourne si le port hôte n'est pas présent */
  232.   IF hostport=NIL THEN RETURN NIL
  233.  
  234.   listnode:=hostport.ln
  235.  
  236.   /* retourne si on ne pas faire un message rexx */
  237.   IF (rexxmsg:=CreateRexxMsg(hostport,'rexx',listnode.name))=NIL THEN RETURN NIL
  238.  
  239.   /* pointeur vers les commandes */
  240.   rexxargs:=rexxmsg.args
  241.  
  242.   /* peut-on créer un argstring? */
  243.   IF temp:=CreateArgstring(command,StrLen(command))
  244.  
  245.     /* met le premier argstring */
  246.     rexxargs[0]:=temp
  247.  
  248.     /* met les flags */
  249.     rexxmsg.action:=RXCOMM OR flags
  250.  
  251.     /* met le pointeur message original dans un pointeur chaine de 16 */
  252.     rexxargs[15]:=unknownmsg
  253.  
  254.     /* interdit le multitache */
  255.     Forbid()
  256.  
  257.     /* envoie notre message vers un port déja existant */
  258.     IF (arexxport:=FindPort(hostname)) THEN PutMsg(arexxport,rexxmsg)
  259.  
  260.     /* permet le multitache */
  261.     Permit()
  262.  
  263.     /* sended? */
  264.     IF arexxport
  265.  
  266.       /* augmente le compteur de non-confirmé */
  267.       INC unconfirmed
  268.  
  269.       /* messages envoyés avec succès */
  270.       RETURN rexxmsg
  271.     ENDIF
  272.   ENDIF
  273.  
  274.   IF temp
  275.     DeleteArgstring(temp)
  276.   ENDIF
  277.   IF rexxmsg
  278.     DeleteRexxMsg(rexxmsg)
  279.   ENDIF
  280.   RETURN NIL
  281. ENDPROC
  282. /* FEND */
  283. /* FOLD "replyRexxMsg(rexxmsg,rc,returnstring)" */
  284. PROC xReplyRexxCmd(rexxmsg:PTR TO rexxmsg,rc,returnstring)
  285.  
  286.   /* met le code de retour */
  287.   rexxmsg.result1:=rc
  288.  
  289.   /* et un pointeur sur la chaine sortante */
  290.   rexxmsg.result2:=IF (rexxmsg.action AND RXFF_RESULT) AND (returnstring<>NIL) THEN CreateArgstring(returnstring,StrLen(returnstring)) ELSE NIL
  291.  
  292. ENDPROC
  293. /* FEND */
  294. /* FOLD "createPort(portname,priority)" */
  295. PROC createPort(portname,priority)
  296.  
  297.   DEF port=NIL:PTR TO mp
  298.   DEF node=NIL:PTR TO ln
  299.  
  300.   /* met le port public? */
  301.   IF portname
  302.  
  303.     /* personne ne fait le même port SVP */
  304.     Forbid()
  305.  
  306.     /* notre port va-t-il être unique ? */
  307.     IF FindPort(portname)=0
  308.  
  309.       /* peut-on faire un port? */
  310.       IF port:=CreateMsgPort()
  311.  
  312.         node:=port.ln
  313.  
  314.         /* rempli le nom */
  315.         node.name:=portname
  316.  
  317.         /* priorité du port public */
  318.         node.pri:=priority
  319.  
  320.         /* et fat ce port public */
  321.         AddPort(port)
  322.       ENDIF
  323.     ENDIF
  324.  
  325.     /* multitache */
  326.     Permit()
  327.  
  328.   /* fait juste un port privé */
  329.   ELSE
  330.  
  331.     /* essaie de faire un port */
  332.     port:=CreateMsgPort()
  333.  
  334.   ENDIF
  335. /* retourne le pointeur au port, ou NIL si le port ne peut être fait (unique) */
  336. ENDPROC port
  337. /* FEND */
  338. /* FOLD "deletePort(port)" */
  339. PROC deletePort(port:PTR TO mp)
  340.  
  341.   DEF node=NIL:PTR TO ln
  342.   DEF msg=NIL:PTR TO mn
  343.  
  344.   /* pointeur donné ? */
  345.   IF port
  346.  
  347.     node:=port.ln
  348.  
  349.     /* si public alors enlêve de la liste public du port */
  350.     IF node.name THEN RemPort(port)
  351.  
  352.     /* plus de message SVP */
  353.     Forbid()
  354.  
  355.     /* enlêve tous les messages à la queue */
  356.     WHILE msg:=GetMsg(port) DO ReplyMsg(msg)
  357.  
  358.     /* efface le port */
  359.     DeleteMsgPort(port)
  360.  
  361.     /* multitache */
  362.     Permit()
  363.   ENDIF
  364. ENDPROC
  365. /* FEND */
  366.  
  367.